package io.lvdaxian.mybatis11.builder.xml;

import io.lvdaxian.mybatis11.builder.BaseBuilder;
import io.lvdaxian.mybatis11.builder.MapperBuilderAssistant;
import io.lvdaxian.mybatis11.mapping.SqlCommandType;
import io.lvdaxian.mybatis11.mapping.SqlSource;
import io.lvdaxian.mybatis11.scripting.LanguageDriver;
import io.lvdaxian.mybatis11.session.Configuration;
import org.dom4j.Element;

import java.util.Locale;

public class XMLStatementBuilder extends BaseBuilder {
  
  // element 元素
  private final Element element;
  // mapper builder 助手
  MapperBuilderAssistant builderAssistant;
  
  public XMLStatementBuilder(Configuration configuration, MapperBuilderAssistant builderAssistant, Element element) {
    super(configuration);
    this.element = element;
    this.builderAssistant = builderAssistant;
  }
  
  /**
   * 从这个方法中 开始解析element 片段
   * <p>
   * //解析语句(select|insert|update|delete)
   * //<select
   * //  id="selectPerson"
   * //  parameterType="int"
   * //  parameterMap="deprecated"
   * //  resultType="hashmap"
   * //  resultMap="personResultMap"
   * //  flushCache="false"
   * //  useCache="true"
   * //  timeout="10000"
   * //  fetchSize="256"
   * //  statementType="PREPARED"
   * //  resultSetType="FORWARD_ONLY">
   * //  SELECT * FROM PERSON WHERE ID = #{id}
   *
   * @author lihh
   */
  public void parseStatementNode() {
    // 拿到 id，就是 select or update 的片段id
    String id = element.attributeValue("id");
    // 参数类型
    String parameterType = element.attributeValue("parameterType");
    Class<?> parameterTypeClass = resolveAlias(parameterType);
    // 外部应用 resultMap
    String resultMap = element.attributeValue("resultMap");
    // 结果类型
    String resultType = element.attributeValue("resultType");
    Class<?> resultTypeClass = resolveAlias(resultType);
    
    // 表示 获取命令名称
    String nodeName = element.getName();
    // 将命令类型 转换为 sql命令类型
    SqlCommandType sqlCommandType = SqlCommandType.valueOf(nodeName.toUpperCase(Locale.ENGLISH));
    
    // 获取默认的语言驱动器
    Class<?> langClass = configuration.getLanguageRegistry().getDefaultDriverClass();
    LanguageDriver langDriver = configuration.getLanguageRegistry().getDriver(langClass);
    
    // element 这个就是 解析 document 元素
    // configuration 配置文件
    // element 元素内容
    // parameterTypeClass 参数类型 class
    SqlSource sqlSource = langDriver.createSqlSource(configuration, element, parameterTypeClass);
    
    // 由构建者 助手来做这个事情了
    builderAssistant.addMappedStatement(
        id,
        sqlSource,
        sqlCommandType,
        parameterTypeClass,
        resultMap,
        resultTypeClass,
        langDriver
    );
  }
}
